package cn.b.training.baby_education_training.api;

import cn.b.training.baby_education_training.entity.UserInfo;
import cn.b.training.baby_education_training.repository.UserInfoRepository;
import cn.b.training.baby_education_training.security.TokenService;
import cn.b.training.baby_education_training.service.SmsService;
import cn.b.training.baby_education_training.service.UserInfoService;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/user")
public class UserInfoController {
    private final TokenService tokenService;
    private final UserInfoService userInfoService;
    private final UserInfoRepository userInfoRepository;
    private final SmsService smsService;
    @Autowired
    AuthenticationManagerBuilder authenticationManagerBuilder;
    @Autowired
    PasswordEncoder passwordEncoder;


    public UserInfoController(TokenService tokenService, UserInfoService userInfoService, UserInfoRepository userInfoRepository, SmsService smsService) {
        this.tokenService = tokenService;
        this.userInfoService = userInfoService;
        this.userInfoRepository = userInfoRepository;
        this.smsService = smsService;
    }

    @PostMapping("/login")
    public ResponseEntity doLogin(@RequestParam(required = true) String phone,
                                  @RequestParam(required = true) String password) {

        //使用用户传入的登录名密码，构造Security的登录名密码认证对象UsernamePasswordAuthenticationToken
        UsernamePasswordAuthenticationToken authenticationToken
                = new UsernamePasswordAuthenticationToken(phone, password);
        UserInfo userInfo = userInfoService.getUser(phone);
        userInfo.setStatus("1");
        userInfo = userInfoRepository.save(userInfo);
        try {
            //2、使用SpringSecurity的验证器对用户身份进行校验authenticate()
            Authentication authentication =
                    authenticationManagerBuilder.getObject().authenticate(authenticationToken);
            //SpringSecurity验证通过后，得到已认证对象authentication，从已认证对象中读取账户数据。
            User authenticatedUser = (User) authentication.getPrincipal();
            //通过用户名获得令牌
            String token = this.tokenService.getToken(authenticatedUser.getUsername());
            JSONObject result = new JSONObject();
            result.put("id_token", token);
            return ResponseEntity.ok(result);
        } catch (Exception e) {
            //发生异常表示登录出错
            return ResponseEntity.status(401).body("用户名密码错误");
        }
    }

    @PostMapping("/regist")
    public ResponseEntity registerAccount(@RequestParam(required = true) String phone,
                                          @RequestParam(required = true) String password,
                                          @RequestParam(required = true) String nickname) {
        try {
            UserInfo account = this.userInfoService.regAccount(phone, password, nickname);
            return ResponseEntity.ok(account);
        } catch (Exception e) {
            e.printStackTrace();
            return ResponseEntity.status(400).body(e.getMessage());
        }
    }

    @GetMapping("/sys/accounts")
    public ResponseEntity getAccounts(@RequestParam(required = false, defaultValue = "0") Integer page,
                                      @RequestParam(required = false, defaultValue = "10") Integer size) {
        Page<UserInfo> result = this.userInfoService.getAllAccounts(page, size);
        return ResponseEntity.ok(result);
    }


    @DeleteMapping("/sys/accounts")
    public ResponseEntity deleteAccount(@RequestParam(required = true) String phone) {
        try {
            boolean result = this.userInfoService.deleteAccount(phone);
            JSONObject code = new JSONObject();
            code.put("success", "删除成功");
            return ResponseEntity.ok(code);
        } catch (Exception e) {
            e.printStackTrace();
            JSONObject error = new JSONObject();
            error.put("errorInfo", e.getMessage());
            return ResponseEntity.status(400).body(error);
        }

    }

    @GetMapping("/userInfo")
    public ResponseEntity getUser(){
        //获取当前登录用户
        Authentication user = SecurityContextHolder.getContext().getAuthentication();
        User currentUser = (User) user.getPrincipal();
        UserInfo userInfo = this.userInfoService.getUser(currentUser.getUsername());
        System.out.println(userInfo);
        //String phone = ((User) SecurityContextHolder.getContext().getAuthentication().getPrincipal()).getUsername();
        //UserInfo account = userInfoService.getUser(phone);
        return ResponseEntity.ok(userInfo);
    }

    /**
     * 发送验证码
     *
     * @param phone
     * @return
     */
    @GetMapping("/send-sms")
    public ResponseEntity sendSms(String phone) {
        //根据手机号码查找账户信息
        UserInfo userAccount = this.userInfoService.getByPhone(phone);
        JSONObject jsonResult = new JSONObject();
        //确定账户存在，发送短信验证码
        if (userAccount != null) {
            //发送验证码
            boolean result = this.smsService.sendValidateSms(phone);
            jsonResult.put("result", result);
            if (result) {
                return ResponseEntity.ok(jsonResult);
            } else {
                return ResponseEntity.status(400).body(jsonResult);
            }
        } else {
            jsonResult.put("result", "未找到用户信息");
            return ResponseEntity.status(400).body(jsonResult);
        }
    }

    @PostMapping("/sms-login")
    public ResponseEntity smsLogin(@RequestParam(required = true) String phone,
                                   @RequestParam(required = true) String validateCode) {
        UserInfo userAccount = this.userInfoService.getByPhone(phone);
        JSONObject jsonResult = new JSONObject();
        if (userAccount != null) {

            //校验输入的验证码
            boolean result = this.smsService.validateSms(phone, validateCode);
            //验证码校验成功，需要根据当前账户，构造jwt令牌返回。
            if (result) {
                String token = null;
                try {
                    userAccount.setStatus("1");
                    userAccount = userInfoRepository.save(userAccount);
                    //使用token服务，返回令牌
                    token = this.tokenService.getToken(userAccount.getPhone());
                    jsonResult.put("id_token", token);
                    return ResponseEntity.ok(jsonResult);
                } catch (Exception e) {
                    e.printStackTrace();
                    jsonResult.put("result", e.getMessage());
                    return ResponseEntity.status(500).body(jsonResult);
                }
            } else {
                jsonResult.put("result", "验证码错误");
                return ResponseEntity.status(401).body(jsonResult);
            }
        }
        //发生异常表示登录出错
        jsonResult.put("result", "未找到用户信息");
        return ResponseEntity.status(401).body(jsonResult);
    }

    @PostMapping(value = "/update/phone")
    public ResponseEntity updatePhone(@RequestParam String phone) {
        try {
            Authentication user = SecurityContextHolder.getContext().getAuthentication();
            User currentUser = (User) user.getPrincipal();
            UserInfo userInfo = this.userInfoService.getUser(currentUser.getUsername());
            if (userInfo != null) {
                userInfo.setPhone(phone);
                userInfoRepository.save(userInfo);
                JSONObject result = new JSONObject();
                result.put("success", "修改成功");
                return ResponseEntity.ok(result);
            } else {
                JSONObject error = new JSONObject();
                error.put("error", "登录身份不合法");
                return ResponseEntity.status(400).body(error);
            }
        } catch (Exception e) {
            JSONObject error = new JSONObject();
            error.put("error", e.getMessage());
            return ResponseEntity.status(400).body(error);
        }
    }

    @PostMapping(value = "/update/nickname")
    public ResponseEntity updateNickname(@RequestParam String nickname) {
        try {
            Authentication user = SecurityContextHolder.getContext().getAuthentication();
            User currentUser = (User) user.getPrincipal();
            UserInfo userInfo = this.userInfoService.getUser(currentUser.getUsername());
            if (userInfo != null) {
                userInfo.setNickname(nickname);
                userInfoRepository.save(userInfo);
                JSONObject result = new JSONObject();
                result.put("success", "修改成功");
                return ResponseEntity.ok(result);
            } else {
                JSONObject error = new JSONObject();
                error.put("error", "登录身份不合法");
                return ResponseEntity.status(400).body(error);
            }
        } catch (Exception e) {
            JSONObject error = new JSONObject();
            error.put("error", e.getMessage());
            return ResponseEntity.status(400).body(error);
        }
    }

    @PostMapping(value = "/update/password")
    public ResponseEntity forgetPassword(@RequestParam String password) {
        try {
            Authentication user = SecurityContextHolder.getContext().getAuthentication();
            User currentUser = (User) user.getPrincipal();
            UserInfo userInfo = this.userInfoService.getUser(currentUser.getUsername());
            if (userInfo != null) {
                userInfo.setPassword(passwordEncoder.encode(password));
                userInfoRepository.save(userInfo);
                JSONObject result = new JSONObject();
                result.put("success", "修改成功");
                return ResponseEntity.ok(result);
            } else {
                JSONObject error = new JSONObject();
                error.put("error", "登录身份不合法");
                return ResponseEntity.status(400).body(error);
            }
        } catch (Exception e) {
            JSONObject error = new JSONObject();
            error.put("error", e.getMessage());
            return ResponseEntity.status(400).body(error);
        }

    }

    @PostMapping(value = "/logout")
    public ResponseEntity logout() {
        try {
            Authentication user = SecurityContextHolder.getContext().getAuthentication();
            User currentUser = (User) user.getPrincipal();
            UserInfo userInfo = this.userInfoService.getUser(currentUser.getUsername());
            String phone = userInfo.getPhone();
            if (userInfo != null) {

                JSONObject result = new JSONObject();
                result.put("success", "注销成功");
                return ResponseEntity.ok(userInfoService.logout(phone));
            } else {
                JSONObject error = new JSONObject();
                error.put("error", "登录身份不合法");
                return ResponseEntity.status(400).body(error);
            }
        } catch (Exception e) {
            JSONObject error = new JSONObject();
            error.put("error", e.getMessage());
            return ResponseEntity.status(400).body(error);
        }

    }
}
